#ifndef __SDTRACE_H__
#define __SDTRACE_H__



#include "qe_def.h"
#include "qe_buffer.h"



typedef struct
{
    /* Start marks, setting in initialization fixed to 'sdtrc-start' */
    char start_mark[16];

    /* Recorder version major.minor.patch */
    qe_u32 version;

    /* Recorder size in bytes */
    qe_u32 size;

    /* Number of data recorded */
    qe_u32 num_datas;

    /* The buffer size, in number of datas */
    qe_u32 max_datas;

    /* Serialize counter */
    qe_u32 serialize_count;

    /* The buffer index, where to write next */
    qe_u32 next_free;

    /* 1 if the buffer is full */
    qe_u32 is_full;

    /* 1 if the recorder has been started */
    qe_u32 is_active;

    /* 'SOFD' */
    qe_u32 data_start_mark;

    qe_u8 datas[0];

    /* 'EOFD' */
    qe_u32 data_end_mark;

    /* End marks, setting in initialization fixed to 'sdtrc-end' */
    char end_mark[16];
}sdtrace_record_data;

typedef enum
{
    SDTRC_STREAM_RB = 0,
    SDTRC_STREAM_WB,
} sdtrace_stream_open_mode;

struct seqdata_trace_stream;
typedef struct seqdata_trace_stream sdtrace_stream;

typedef struct seqdata_trace_stream
{
    qe_ret (*open)(sdtrace_stream *, qe_u8, qe_uint);
    qe_int (*read)(sdtrace_stream *, qe_u8 *, qe_uint);
    qe_int (*write)(sdtrace_stream *, qe_u8 *, qe_uint);
    qe_ret (*close)(sdtrace_stream *);
    void *user;
}sdtrace_stream;

typedef struct
{
    sdtrace_stream *stream;

    qe_ringq *ring;

    sdtrace_record_data record;

    qe_bool is_initialized;
}sdtracer;



sdtracer *sdtracer_new(qe_uint size, qe_uint num);

qe_ret sdtracer_set_stream(sdtracer *tracer, sdtrace_stream *writer);

qe_ret sdtracer_record(sdtracer *tracer, qe_const_ptr data);

qe_ret sdtracer_load(sdtracer *tracer);
qe_ret sdtracer_load_from_gbuf(sdtracer *tracer, qe_gbuf *buf);

qe_ret sdtracer_serialize(sdtracer *tracer);
qe_ret sdtracer_serialize_to_gbuf(sdtracer *tracer, qe_gbuf **pbuf);

void sdtracer_destroy(sdtracer *tracer);



#endif /* __SDTRACE_H__ */